package proyecto1IA;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
import javax.swing.*;

public class FrameJuego extends JFrame implements ActionListener {

    public PanelJuego paneljuego;
    public static JMenuItem cambiarFondo, nuevaPartida, abandonarPartida, salir, acercaDe;
    public static JMenu noInformados, informados;
    public static JMenuItem amplitud, profundidad, costoUniforme, voraz, aEstrella;
    public static JPanelFondo panelFondo;
    public static boolean panelActivado = false;

    public FrameJuego() {

        super("Sorting Robot!");
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (Exception ex) {

            JOptionPane.showMessageDialog(null, "Imposible modificar el tema visual", "", JOptionPane.ERROR_MESSAGE);

        }

        panelFondo = new JPanelFondo();

        // Barra de menu
        JMenuBar barra = new JMenuBar();
        setJMenuBar(barra);

        //Menu de Archivo(1)
        JMenu menuArchivo = new JMenu("Archivo");
        barra.add(menuArchivo);
        menuArchivo.setMnemonic('A');

        //Menu nueva partida y salir
        nuevaPartida = new JMenuItem("Nuevo");
        nuevaPartida.addActionListener(this);
        salir = new JMenuItem("Salir");
        salir.addActionListener(this);

        //Agregar a Archivo nueva Partida y Sali ~++~
        menuArchivo.add(nuevaPartida);
        menuArchivo.add(salir);

        //Menu de Juego(2)
        JMenu menuJuego = new JMenu("Juego");
        barra.add(menuJuego);
        menuJuego.setMnemonic('J');

        //Menu cambiar fondo, abandonar partida y mostrar puntuaciones.
        cambiarFondo = new JMenuItem("Cambiar imagen de fondo");
        cambiarFondo.addActionListener(this);
        abandonarPartida = new JMenuItem("Abandonar Partida");

        abandonarPartida.setEnabled(false);

        abandonarPartida.addActionListener(this);

        //Agregar a Juego cambiar fondo, abandonar partida y mostrar puntuaciones ~++~
        menuJuego.add(cambiarFondo);
        menuJuego.add(abandonarPartida);

        //Menu de Algoritmos
        JMenu menuAlgoritmos = new JMenu("Algoritmos");
        barra.add(menuAlgoritmos);
        menuAlgoritmos.setMnemonic('L');

        noInformados = new JMenu("No Informados");

        amplitud = new JMenuItem("Amplitud");
        amplitud.addActionListener(this);
        profundidad = new JMenuItem("Profundidad");
        profundidad.addActionListener(this);
        costoUniforme = new JMenuItem("Costo Unifome");
        costoUniforme.addActionListener(this);

        noInformados.add(amplitud);
        noInformados.add(profundidad);
        noInformados.add(costoUniforme);

        informados = new JMenu("Informados");

        voraz = new JMenuItem("Voraz");
        voraz.addActionListener(this);
        aEstrella = new JMenuItem("A Estrella (A*)");
        aEstrella.addActionListener(this);

        informados.add(voraz);
        informados.add(aEstrella);

        menuAlgoritmos.add(noInformados);
        menuAlgoritmos.add(informados);


        //Menu de Ayuda
        JMenu menuAyuda = new JMenu("Ayuda");
        barra.add(menuAyuda);
        menuAyuda.setMnemonic('y');

        //Menu cambiar fondo, abandonar partida y mostrar puntuaciones.
        ImageIcon imagen = new ImageIcon(getClass().getResource("about.png"));

        //Items Manual Y acerca      
        acercaDe = new JMenuItem("Acerca De", imagen);
        acercaDe.addActionListener(this);

        //Agregar Acerca      
        menuAyuda.add(acercaDe);
        add(panelFondo);

    }

    public void limpiarPanelJuego() {

        if (panelActivado == true) {

            panelFondo.remove(paneljuego);
            abandonarPartida.setEnabled(false);
            panelActivado = false;

        }
    }

    public void actionPerformed(ActionEvent evento) {

        Archivo archivo = new Archivo();

        if (evento.getSource() == nuevaPartida) {
            try { //Scanner try

                limpiarPanelJuego();

                Scanner entrada = new Scanner(new File(archivo.obtenerRuta()));
                paneljuego = new PanelJuego(entrada);
                paneljuego.setVisible(true);
                panelActivado = true;
                abandonarPartida.setEnabled(true);

                panelFondo.add(paneljuego, BorderLayout.CENTER);

                //Revalidar y repintar el Panel.
                paneljuego.revalidate();

            } catch (FileNotFoundException ex) { //Scanner Catch
                System.out.println("Error al abrir el archivo.");
            }

        }

        if (evento.getSource() == cambiarFondo) {

            panelFondo.setImagen(archivo.obtenerRuta());

        }

        if (evento.getSource() == salir) {
            System.exit(0);
        }

        if (evento.getSource() == amplitud) {

            System.out.println("***Activando Amplitud***");

            Amplitud algoritmoAmplitud = new Amplitud(PanelJuego.matrizPosiciones, PanelJuego.robot, PanelJuego.objeto1, PanelJuego.objeto2, PanelJuego.lugar1, PanelJuego.lugar2);

            long empieza = System.nanoTime();
            ArrayList<ArrayList<Point>> solucion = algoritmoAmplitud.controladorAmplitud();
            long termina = System.nanoTime();

            long tiempo = termina - empieza;
            long segundos = TimeUnit.SECONDS.convert(tiempo, TimeUnit.NANOSECONDS);

            int nodos = algoritmoAmplitud.getNodos();
            int profundidad = (solucion.get(0).size() + solucion.get(1).size() + +solucion.get(2).size() + solucion.get(3).size());

            String caminoRecorrido = "";

            System.out.println("La profundidad es: " + profundidad);
            System.out.println("Los nodos expandidos fueron: " + nodos);

            System.out.println("El tiempo de respuesta fue: " + segundos + " segundos");
            System.out.println("El tiempo de respuesta fue: " + tiempo + " nanosegundos.");

            for (int fila = 0; fila < solucion.size(); fila++) {
                for (int columna = 0; columna < solucion.get(fila).size(); columna++) {
                    caminoRecorrido += "(" + solucion.get(fila).get(columna).x + ", "
                            + solucion.get(fila).get(columna).y + ") ";
                    System.out.print(solucion.get(fila).get(columna) + " ");
                    if ((columna + 1) % 12 == 0) {
                        caminoRecorrido += "\n";
                    }
                }
                caminoRecorrido += "\n";
                System.out.println("\n");
            }

            JOptionPane.showMessageDialog(null, "\tAmplitud" + "\nCantidad de nodos expandidos: " + nodos
                    + "\nProfundidad del árbol: " + profundidad
                    + "\nTiempo de cómputo en nanosegundos: " + tiempo
                    + "\nTiempo de cómputo en segundos: " + segundos
                    + "\nEl camino recorrido fue: \n" + caminoRecorrido);

            paneljuego.inicializarSolucion(solucion);
            paneljuego.hilo.start();
            //paneljuego.dibujarCamino(solucion);
            //*Revalidar y repintar el Panel.
            //paneljuego.revalidate();

        }

        if (evento.getSource() == profundidad) {

            System.out.println("***Activando profundidad***");

            Profundidad algoritmoProfundidad = new Profundidad(PanelJuego.matrizPosiciones, PanelJuego.robot, PanelJuego.objeto1, PanelJuego.objeto2, PanelJuego.lugar1, PanelJuego.lugar2);

            long empieza = System.nanoTime();
            ArrayList<ArrayList<Point>> solucion = algoritmoProfundidad.controladorProfundidad();
            long termina = System.nanoTime();

            long tiempo = termina - empieza;
            long segundos = TimeUnit.SECONDS.convert(tiempo, TimeUnit.NANOSECONDS);

            int profundidad = algoritmoProfundidad.getProfundidad();
            int nodos = algoritmoProfundidad.getNodos();

            String caminoRecorrido = "";

//            System.out.println("El tamaño del arreglo es: " + (solucion.get(0).size()
//                    + solucion.get(1).size() + + solucion.get(2).size() + solucion.get(3).size()));
            System.out.println("La profundidad es: " + profundidad);
            System.out.println("Los nodos expandidos fueron: " + nodos);
            System.out.println("El tiempo de respuesta fue: " + segundos + " segundos");
            System.out.println("El tiempo de respuesta fue: " + tiempo + " nanosegundos.");

            for (int fila = 0; fila < solucion.size(); fila++) {
                for (int columna = 0; columna < solucion.get(fila).size(); columna++) {

                    caminoRecorrido += "(" + solucion.get(fila).get(columna).x + ", "
                            + solucion.get(fila).get(columna).y + ") ";
                    System.out.print(solucion.get(fila).get(columna) + " ");
                    if ((columna + 1) % 12 == 0) {
                        caminoRecorrido += "\n";
                    }
                }
                caminoRecorrido += "\n";
                System.out.println("\n");
            }

            JOptionPane.showMessageDialog(null, "\tProfundidad" + "\nCantidad de nodos expandidos: " + nodos
                    + "\nProfundidad del árbol: " + profundidad
                    + "\nTiempo de cómputo en nanosegundos: " + tiempo
                    + "\nTiempo de cómputo en segundos: " + segundos
                    + "\nEl camino recorrido fue: \n" + caminoRecorrido);

            paneljuego.inicializarSolucion(solucion);
            paneljuego.hilo.start();
        }

        if (evento.getSource() == costoUniforme) {

            System.out.println("***Activando Costo Uniforme***");

            CostoUniforme algoritmoCostoUniforme = new CostoUniforme(PanelJuego.matrizPesos, PanelJuego.robot, PanelJuego.objeto1, PanelJuego.objeto2, PanelJuego.lugar1, PanelJuego.lugar2);
            long empieza = System.nanoTime();
            ArrayList<ArrayList<Point>> solucion = algoritmoCostoUniforme.controladorCostoUniforme();
            long termina = System.nanoTime();

            long tiempo = termina - empieza;
            long segundos = TimeUnit.SECONDS.convert(tiempo, TimeUnit.NANOSECONDS);

            int profundidad = algoritmoCostoUniforme.getProfundidad();
            int nodos = algoritmoCostoUniforme.getNodos();

            String caminoRecorrido = "";

            System.out.println("La profundidad es: " + profundidad);
            System.out.println("Los nodos expandidos fueron: " + nodos);

            System.out.println("El tiempo de respuesta fue: " + segundos + " segundos");
            System.out.println("El tiempo de respuesta fue: " + tiempo + " nanosegundos.");

            for (int fila = 0; fila < solucion.size(); fila++) {
                for (int columna = 0; columna < solucion.get(fila).size(); columna++) {

                    caminoRecorrido += "(" + solucion.get(fila).get(columna).x + ", "
                            + solucion.get(fila).get(columna).y + ") ";
                    System.out.print(solucion.get(fila).get(columna) + " ");
                    if ((columna + 1) % 12 == 0) {
                        caminoRecorrido += "\n";
                    }
                }
                caminoRecorrido += "\n";
                System.out.println("\n");
            }

            JOptionPane.showMessageDialog(null, "\tCosto Uniforme" + "\nCantidad de nodos expandidos: " + nodos
                    + "\nProfundidad del árbol: " + profundidad
                    + "\nTiempo de cómputo en nanosegundos: " + tiempo
                    + "\nTiempo de cómputo en segundos: " + segundos
                    + "\nEl camino recorrido fue: \n" + caminoRecorrido);

            paneljuego.inicializarSolucion(solucion);
            paneljuego.hilo.start();

        }

        if (evento.getSource() == voraz) {

            System.out.println("***Activando Costo Avara***");

            Avara vorazAlgoritmo = new Avara(PanelJuego.matrizPesos, PanelJuego.robot, PanelJuego.objeto1, PanelJuego.objeto2, PanelJuego.lugar1, PanelJuego.lugar2);

            ArrayList<ArrayList<Point>> solucion;
            long empieza = System.nanoTime();
            solucion = vorazAlgoritmo.controladorAvara();
            long termina = System.nanoTime();

            long tiempo = termina - empieza;
            long segundos = TimeUnit.SECONDS.convert(tiempo, TimeUnit.NANOSECONDS);
            System.out.println("El tiempo de respuesta fue: " + segundos + " segundos");
            System.out.println("El tiempo de respuesta fue: " + tiempo + " nanosegundos.");

            System.out.println("La solución es: ");


            for (int fila = 0; fila < solucion.size(); fila++) {
                for (int columna = 0; columna < solucion.get(fila).size(); columna++) {
                    System.out.print(solucion.get(fila).get(columna) + " ");
                }
                System.out.println("\n");
            }

            paneljuego.inicializarSolucion(solucion);
            paneljuego.hilo.start();

        }

        if (evento.getSource() == aEstrella) {
            System.out.println("***Activando Costo AEstrella***");

            AEstrella algoritmoAEstrella = new AEstrella(PanelJuego.matrizPesos, PanelJuego.robot, PanelJuego.objeto1, PanelJuego.objeto2, PanelJuego.lugar1, PanelJuego.lugar2);

            ArrayList<ArrayList<Point>> solucion;
            long empieza = System.nanoTime();
            solucion = algoritmoAEstrella.controladorAEstrella();
            long termina = System.nanoTime();

            long tiempo = termina - empieza;
            long segundos = TimeUnit.SECONDS.convert(tiempo, TimeUnit.NANOSECONDS);
            System.out.println("El tiempo de respuesta fue: " + segundos + " segundos");
            System.out.println("El tiempo de respuesta fue: " + tiempo + " nanosegundos.");

            for (int fila = 0; fila < solucion.size(); fila++) {
                for (int columna = 0; columna < solucion.get(fila).size(); columna++) {
                    System.out.print(solucion.get(fila).get(columna) + " ");
                }
                System.out.println("\n");
            }

            paneljuego.inicializarSolucion(solucion);
            paneljuego.hilo.start();

        }

        if (evento.getSource() == acercaDe) {

            ImageIcon imagen = new ImageIcon(getClass().getResource("iconoAcercaDe.png"));

            JOptionPane.showMessageDialog(FrameJuego.this, "Agentes!\nVersión 1.0\nDesarrollado Por: Juan Manuel Olaya, John Andrés Medina y Luis Felipe Murillo\n"
                    + "Inteligencia Artificial 2013\nOctubre De 2013", "Acerca De", JOptionPane.DEFAULT_OPTION, imagen);

        }

        if (evento.getSource() == abandonarPartida) {

            limpiarPanelJuego();
        }

    }// fin actionPerformed
}
